package nl.hro.mgdd.team4.raidersofhexagoniland.Scenes;

import java.io.IOException;
import java.io.InputStream;

import nl.hro.mgdd.team4.raidersofhexagoniland.GameActivity;

import org.andengine.entity.scene.Scene;
import org.andengine.entity.sprite.ButtonSprite;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.sprite.ButtonSprite.OnClickListener;
import org.andengine.opengl.texture.ITexture;
import org.andengine.opengl.texture.bitmap.BitmapTexture;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.TextureRegionFactory;
import org.andengine.util.adt.io.in.IInputStreamOpener;
import org.andengine.util.debug.Debug;

import Parts.HexagonTile;
import Parts.HexagonTile.HexagonState;
import Utils.Array;
import Utils.Vector2;

public class LevelBaseScene extends Scene implements OnClickListener {
	protected Array<HexagonTile> _tiles = new Array<HexagonTile>();
	protected static HexagonTile[][] _map;

	protected Vector2 _origin;

	protected ITexture _occHex;
	protected ITexture _freeHex;
	protected ITexture _finHex;
	protected ITexture _baracks;
	protected ITextureRegion _occRegion;
	protected ITextureRegion _freeRegion;
	protected ITextureRegion _finRegion;
	protected ITextureRegion _baracksRegion;
	
	protected ITexture _levelBackground;
	protected ITextureRegion _levelBackgroundRegion;

	public Array<HexagonTile> getTiles() {
		return _tiles;
	}

	protected void loadResources() {
		try {
			SceneManager.getManager();
			_occHex = new BitmapTexture(SceneManager._game.getTextureManager(),
					new IInputStreamOpener() {

						@Override
						public InputStream open() throws IOException {
							SceneManager.getManager();
							return SceneManager._game.getAssets().open(
									"gfx/tileSand.png");
						}
					});
			_occHex.load();
			_occRegion = TextureRegionFactory.extractFromTexture(_occHex);

			_finHex = new BitmapTexture(SceneManager._game.getTextureManager(),
					new IInputStreamOpener() {

						@Override
						public InputStream open() throws IOException {
							SceneManager.getManager();
							return SceneManager._game.getAssets().open(
									"gfx/tileLava.png");
						}
					});
			_finHex.load();
			_finRegion = TextureRegionFactory.extractFromTexture(_finHex);

			_freeHex = new BitmapTexture(
					SceneManager._game.getTextureManager(),
					new IInputStreamOpener() {

						@Override
						public InputStream open() throws IOException {
							SceneManager.getManager();
							return SceneManager._game.getAssets().open(
									"gfx/tileGrass.png");
						}
					});
			_freeHex.load();
			_freeRegion = TextureRegionFactory.extractFromTexture(_freeHex);
			
			_baracks = new BitmapTexture(SceneManager._game.getTextureManager(), new IInputStreamOpener() {
				
				@Override
				public InputStream open() throws IOException {
					SceneManager.getManager();
					return SceneManager._game.getAssets().open("gfx/baracks.png");
				}
			});
			_baracks.load();
			_baracksRegion = TextureRegionFactory.extractFromTexture(_baracks);
			
			_levelBackground = new BitmapTexture(SceneManager._game.getTextureManager(), new IInputStreamOpener() {
				
				@Override
				public InputStream open() throws IOException {
					SceneManager.getManager();
					return SceneManager._game.getAssets().open("gfx/Level" + SceneManager.getManager().getLevelNumber() + ".png");
				}
			});
			_levelBackground.load();
			_levelBackgroundRegion = TextureRegionFactory.extractFromTexture(_levelBackground);
		} catch (IOException e) {
			Debug.e(e);
		}

		attachChild(new Sprite(0f, 0f, _levelBackgroundRegion, SceneManager._game.getVertexBufferObjectManager()));
		for (HexagonTile h : _tiles) {
			Sprite s;
			switch (h.getState()) {
			case StartTile:
				s = new ButtonSprite(getXToUse(h), getYToUse(h), _freeRegion,
						SceneManager._game.getVertexBufferObjectManager(), this);
				break;
			case FinishTile:
				s = new ButtonSprite(getXToUse(h), getYToUse(h), _finRegion,
						SceneManager._game.getVertexBufferObjectManager(), this);
				break;
			case Free:
				s = new ButtonSprite(getXToUse(h), getYToUse(h), _freeRegion,
						SceneManager._game.getVertexBufferObjectManager(), this);
				break;
			case Occupied:
				s = new ButtonSprite(getXToUse(h), getYToUse(h), _occRegion,
						SceneManager._game.getVertexBufferObjectManager(), this);
				break;
			case Baracks:
				s = new ButtonSprite(getXToUse(h), getYToUse(h), _baracksRegion, SceneManager._game.getVertexBufferObjectManager(), this);
				break;
			default:
				s = new ButtonSprite(getXToUse(h), getYToUse(h), _occRegion,
						SceneManager._game.getVertexBufferObjectManager(), this);
				break;
			}
			s.setTag(h.getTag());
			registerTouchArea(s);
			attachChild(s);
		}
		setTouchAreaBindingOnActionDownEnabled(true);
	}

	public void setBattleResult(HexagonTile h) {
		for (HexagonTile ht : _tiles) {
			if (ht.getPositionArray().x == h.getPositionArray().x
					&& ht.getPositionArray().y == h.getPositionArray().y) {
				_tiles.set(_tiles.indexOf(ht, true), h);
				break;
			}
		}
		_map[(int) h.getPositionArray().x][(int) h.getPositionArray().y] = new HexagonTile(
				new Vector2(h.getPositionArray().x, h.getPositionArray().y),
				h.getState(), h.getUnits(), h.getTag());
		detachChild(h.getTag());
		Sprite s;
		switch (h.getState()) {
		case Free:
			s = new ButtonSprite(getXToUse(h), getYToUse(h), _freeRegion,
					SceneManager._game.getVertexBufferObjectManager(), this);
			break;
		case Occupied:
			s = new ButtonSprite(getXToUse(h), getYToUse(h), _occRegion,
					SceneManager._game.getVertexBufferObjectManager(), this);
			break;
		case FinishTile:
			s = new ButtonSprite(getXToUse(h), getYToUse(h), _finRegion,
					SceneManager._game.getVertexBufferObjectManager(), this);
			break;
		case Baracks:
			s = new ButtonSprite(getXToUse(h), getYToUse(h), _freeRegion,
					SceneManager._game.getVertexBufferObjectManager(), this);
		default:
			s = new ButtonSprite(getXToUse(h), getYToUse(h), _occRegion,
					SceneManager._game.getVertexBufferObjectManager(), this);
			break;
		}
		s.setTag(h.getTag());
		registerTouchArea(s);
		attachChild(s);
	}

	protected float getXToUse(HexagonTile h) {
		float mapWidth = 0f;
		switch(SceneManager.getManager().getLevelNumber()){
		case 1:
			mapWidth = 3f;
			break;
		case 2:
			mapWidth = 3f;
			break;
		case 3:
			mapWidth = 5f;
			break;
		case 4:
			mapWidth = 5f;
			break;
		case 5:
			mapWidth = 6f;
			break;
		}
		mapWidth = mapWidth * _occRegion.getWidth();
		return h.getPositionWorld().x + _origin.x
				+ (GameActivity.getCamera().getWidth() / 2f - mapWidth / 2f);
	}

	protected float getYToUse(HexagonTile h) {
		float mapHeight = 0f;
		switch(SceneManager.getManager().getLevelNumber()){
		case 1:
			mapHeight = 2f;
			break;
		case 2:
			mapHeight = 4f;
			break;
		case 3:
			mapHeight = 3f;
			break;
		case 4:
			mapHeight = 4f;
			break;
		case 5:
			mapHeight = 3f;
			break;
		}
		mapHeight = mapHeight * _occRegion.getHeight();
		return h.getPositionWorld().y + _origin.y
				+ (GameActivity.getCamera().getHeight() / 2f - mapHeight / 2f);
	}

	protected boolean canTileBeAttacked(HexagonTile h) {
		boolean returnValue = false;
		Vector2 v = h.getPositionArray();
		int minX = (int) (v.x - 1 < 0 ? 0 : v.x - 1), maxX = (int) (v.x + 2 > SceneManager
				.getManager().getLevelSize().x ? SceneManager.getManager()
				.getLevelSize().x : v.x + 2);
		int minY = (int) (v.y - 1 < 0 ? 0 : v.y - 1), maxY = (int) (v.y + 2 > SceneManager
				.getManager().getLevelSize().y ? SceneManager.getManager()
				.getLevelSize().y : v.y + 2);
		for (int x = minX; x < maxX; x++) {
			for (int y = minY; y < maxY; y++) {
				if ((x == (int) (v.x - 1) && y == (int) (v.y + 1))
						|| x == (int) (v.x + 1) && y == (int) (v.y - 1))
					continue;
				if (_map[x][y] != null) {
					if (_map[x][y].getState() == HexagonState.Free
							|| _map[x][y].getState() == HexagonState.StartTile)
						returnValue = true;
				}
			}
		}
		return returnValue;
	}

	@Override
	public void onClick(ButtonSprite pButtonSprite, float pTouchAreaLocalX,
			float pTouchAreaLocalY) {
		HexagonTile selectedTile = null;
		for (HexagonTile h : _tiles) {
			if (h.getTag() == pButtonSprite.getTag()) {
				selectedTile = h;
				break;
			}
		}
		if (selectedTile == null)
			return;
		else if (selectedTile.getState() == HexagonState.Free
				|| selectedTile.getState() == HexagonState.StartTile)
			return;
		else if (canTileBeAttacked(selectedTile)) {
			if (selectedTile.getState() == HexagonState.FinishTile) {
				SceneManager.getManager().setNextLevel();
				return;
			}
			if (selectedTile.getState() == HexagonState.Baracks) {
				switch (SceneManager.getManager().getLevelNumber()) {
				case 4:
					SceneManager._player.setPLayerUnits(
							SceneManager._player.getSwordCount(),
							SceneManager._player.getBowCount() + 3,
							SceneManager._player.getSpearCount() + 1);
					break;
				case 5:
					SceneManager._player.setPLayerUnits(
							SceneManager._player.getSwordCount(),
							SceneManager._player.getBowCount() + 1,
							SceneManager._player.getSpearCount() + 3);
					break;
				}
				setBattleResult(selectedTile);
			} else {
				BattleSetupScene bss = new BattleSetupScene(selectedTile);
				this.setChildScene(bss);
			}
		} else
			return;
	}

	public int getMapWidth() {
		return 0;
	}

	public int getMapHeight() {
		return 0;
	}
}
